﻿//#define  _CRT_SECURE_NO_WARNINGS

//class HeapOnly
//{
//public:
//	static HeapOnly* CreateObject()
//	{
//		return new HeapOnly;
//	}
//private:
//	HeapOnly() {}
//
//	// C++98
//	// 1.只声明,不实现。因为实现可能会很麻烦，而你本身不需要
// // 2.声明成私有
//	HeapOnly(const HeapOnly&);
//
//		// or
//
//		// C++11    
//		HeapOnly(const HeapOnly&) = delete;
//};


//#include<iostream>
//using namespace std;
//
//class HeapOnly
//{
//public:
//	//CreateObject是一个成员函数，要调用成员函数需要有对象
//	//这里变为：要想创建对象就要调用这个函数，要想调用这个函数就要先有对象
//	//即“先有鸡还是先有蛋？的问题”
//	//那就可以将CreateObject成员函数设置成静态的
//	//new 创建对象，会调用构造函数，而构造函数是成员函数中比较特殊的
//	//普通的非静态成员函数需要使用对象去调用，而构造函数不需要
//	//静态的使得this指针不能访问静态的成员，但可以访问静态构造函数
//	//构造函数不用this指针去调用
//	static HeapOnly* CreateObject()
//	{
//		return new HeapOnly;
//	}
//
//private:
//	//构造函数私有
//	HeapOnly() {}
//};
//
//int main()
//{
	//////常用创建类对象方式
	////HeapOnly h1;                    //在局部
	////static HeapOnly h2;             //在静态区
	////HeapOnly* ph3 = new HeapOnly;   //在栈上

//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class HeapOnly
//{
//public:
//	//CreateObject是一个成员函数，要调用成员函数需要有对象
//	//这里变为：要想创建对象就要调用这个函数，要想调用这个函数就要先有对象
//	//即“先有鸡还是先有蛋？的问题”
//	//那就可以将CreateObject成员函数设置成静态的
//	//new 创建对象，会调用构造函数，而构造函数是成员函数中比较特殊的
//	//普通的非静态成员函数需要使用对象去调用，而构造函数不需要
//	//静态的使得this指针不能访问静态的成员，但可以访问静态构造函数
//	//构造函数不用this指针去调用
//	static HeapOnly* CreateObject()
//	{
//		return new HeapOnly;
//	}
//
//private:
//	//构造函数私有
//	HeapOnly() {}
//};
//
//int main()
//{
//	////常用创建类对象方式
//	//HeapOnly h1;                    //在局部
//	//static HeapOnly h2;             //在静态区
//	//HeapOnly* ph3 = new HeapOnly;   //在栈上
//
//	HeapOnly* ph4 = HeapOnly::CreateObject();
//	HeapOnly* ph5 = HeapOnly::CreateObject();
//
//	delete ph4;
//	delete ph5;
//
//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class HeapOnly
//{
//public:
//	//CreateObject是一个成员函数，要调用成员函数需要有对象
//	//这里变为：要想创建对象就要调用这个函数，要想调用这个函数就要先有对象
//	//即“先有鸡还是先有蛋？的问题”
//	//那就可以将CreateObject成员函数设置成静态的
//	//new 创建对象，会调用构造函数，而构造函数是成员函数中比较特殊的
//	//普通的非静态成员函数需要使用对象去调用，而构造函数不需要
//	//静态的使得this指针不能访问静态的成员，但可以访问静态构造函数
//	//构造函数不用this指针去调用
//	static HeapOnly* CreateObject()
//	{
//		return new HeapOnly;
//	}
//private:
//	//构造函数私有
//	HeapOnly() {}
//
//	//拷贝构造函数
//	// C++98
//	// 1.只声明,不实现。因为实现可能会很麻烦，而你本身不需要
//	// 2.声明成私有
//	//HeapOnly(const HeapOnly&);
//
//	// or
//
//	// C++11    
//	HeapOnly(const HeapOnly&) = delete;
//};
//int main()
//{
//	////常用创建类对象方式
//	//HeapOnly h1;                    //在局部
//	//static HeapOnly h2;             //在静态区
//	//HeapOnly* ph3 = new HeapOnly;   //在栈上
//	HeapOnly* ph4 = HeapOnly::CreateObject();
//	HeapOnly* ph5 = HeapOnly::CreateObject();
//
//	//HeapOnly copy(*ph4);
//	delete ph4;
//	delete ph5;
//
//	return 0;
//}



//#include<iostream>
//using namespace std;
//class StackOnly
//{
//public:
	//static StackOnly CreateObj()
	//{
	//	 return  StackOnly();  //直接传值返回，编译器会优化，将：构造+拷贝构造——>构造
	//	/* StackOnly st;
	//	 return st;*/
	//}
//	//StackOnly(const StackOnly&) = delete;
//	void Print()
//	{
//		cout << "StackOnly" << endl;
//	}
//private:
//	//构造函数私有化
//	StackOnly()
//		:_a(0)
//	{}
//
//	int _a;
//};
//
//int main()
//{
//	//常用创建类对象方式
//	StackOnly h1=StackOnly::CreateObj();         //在局部
//	StackOnly::CreateObj().Print();       //不使用对象接收
//	//static StackOnly h2;                       //在静态区
//	//StackOnly* ph3 = new StackOnly;            //在栈上
//	
//	return 0;
//}

//#include<iostream>
//using namespace std;
//class StackOnly
//{
//public:
//
//	// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
//	// StackOnly obj = StackOnly::CreateObj();
//	// StackOnly* ptr3 = new StackOnly(obj);
//	void* operator new(size_t size) = delete;
//	
//
//};
//StackOnly st;                        //全局的也没有禁掉
//int main()
//{
//	//StackOnly* p1 = new StackOnly;   //禁掉了new
//	StackOnly s1;                    
//	static StackOnly s2;             //静态的没有禁掉
//	return 0;
//}


//#include<iostream>
//using namespace std;
//class StackOnly
//{
//public:
//	static StackOnly CreateObj()
//	{
//		return  StackOnly();  //直接传值返回，编译器会优化，将：构造+拷贝构造——>构造
//	}
//	// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
//	void* operator new(size_t size) = delete;
//	void operator delete(void* p) = delete;
//private:
//	//构造函数
//	StackOnly()
//		:_a(0)
//	{}
//
//	int _a;
//};
//
//int main()
//{
//    StackOnly obj = StackOnly::CreateObj();
//	//StackOnly* ptr3 = new StackOnly(obj);
//	static StackOnly copy(obj);
//
//	return 0;
//}

//HeapOnly::DeleteObj(ph3);

//#include<iostream>
//using namespace std;
//class HeapOnly
//{
//public:
//	HeapOnly()
//	{}
//	
//	void DeleteObj()
//	{
//		delete this;
//	}
//private: 
//	//析构函数私有
//	~HeapOnly() 
//	{}
//};
//
//int main()
//{
//	//常用创建类对象方式
//	//HeapOnly h1;                    //在局部
//	//static HeapOnly h2;             //在静态区
//	HeapOnly* ph3 = new HeapOnly;   //在栈上
//
//	//delete ph3;
//	ph3->DeleteObj();
//	
//	return 0;
//} 

//Singleton Singleton::m_instance;  // 在程序入口之前就完成单例对象的初始化

// 饿汉模式
// 优点：简单
// 缺点：可能会导致进程启动慢，且如果有多个单例类对象实例启动顺序不确定。

//// 饿汉模式——一开始（main函数之前）就创建
//#include<iostream>
//using namespace std;
//class Singleton
//{
//public:
//	static Singleton* GetInstance()
//	{
//		return &m_instance;
//	}
//	void Print();                     //声明
//	
//private:
//	// 构造函数私有
//	Singleton()
//	{}
//	int _a;
//	Singleton(const Singleton&) = delete;
//	static Singleton m_instance;      //声明      
//};
//
//Singleton Singleton::m_instance;     // 定义
//
//void Singleton::Print()              //定义
//{
//	cout << _a << endl;
//}
//int main()
//{
//	//GetInstance()可以获取到这个Singleton类的单例对象
//	Singleton::GetInstance()->Print();
//	//Singleton st1;
//	//Singleton* st2 = new Singleton;
//	Singleton copy(*Singleton::GetInstance());
//
//	//cout << sizeof(Singleton) << endl;
//	return 0;
//}


//#include<iostream>
//using namespace std;
//class Singleton
//{
//public:
//	static Singleton* GetInstance()
//	{
//		return &m_instance;
//	}
//private:
//	// 构造函数私有
//	Singleton()
//	{}
//	int _a;
//	//Singleton m_instance;               //error,如果没有限制，将会递归下去
//	static Singleton m_instance;        //静态的对象只是受到类域的限制，而是属于全部的类，就像全局变量一样
//};
//
//static Singleton m_instance;  
//
//int main()
//{
//	cout << sizeof(Singleton) << endl;
//	return 0;
//}

//
//#include<iostream>
//#include<string>
//using namespace std;
//
//class InforMgr
//{
//public:
//	static InforMgr* GetInstance()
//	{
//		return _spInst;
//	}
//private:
//	InforMgr()
//	{}
//
//	InforMgr(const InforMgr&) = delete;
//	string _address;
//	int _secretKey;
//
//	static InforMgr* _spInst;   //声明
//};
//
//InforMgr* InforMgr::_spInst = new InforMgr;
//int main()
//{
//	InforMgr s1;
//	static InforMgr s2;
//	InforMgr* s3 =new InforMgr;
//
//	InforMgr::GetInstance();
//	return 0;
//}


#include<iostream>
#include<string>
using namespace std;

//InforMgr 单例模式
//懒汉模式——一开始不创建对象，第一次调用GetInstance再创建对象
class InforMgr
{
public:
	static InforMgr* GetInstance()
	{
		//多线程同时调用，还需要加锁
		if (_spInst == nullptr)
		{
			 _spInst  = new InforMgr;
		}
		return  _spInst;
	}

	void SetAddress(const string& s)
	{
		_address = s;
	}
	string& GetAddress()
	{
		return _address;
	}
private:
	InforMgr()
	{}

	InforMgr(const InforMgr&) = delete;
	string _address;
	int _secretKey;

	static InforMgr* _spInst;   //声明
};

InforMgr* InforMgr::_spInst = new InforMgr;
int main()
{
	/*InforMgr s1;
	static InforMgr s2;
	InforMgr* s3 = new InforMgr;*/

	//全局只有一个InfoMgr对象
	InforMgr::GetInstance()->SetAddress("中国");

	cout << InforMgr::GetInstance()->GetInstance() << endl;
	return 0;
}